package com.xdf.ecommerce.service.impl;

import com.alibaba.fastjson.JSON;
import com.xdf.ecommerce.constant.GoodsConstant;
import com.xdf.ecommerce.dao.EcommerceGoodsMapper;
import com.xdf.ecommerce.entity.EcommerceGoods;
import com.xdf.ecommerce.goods.DeductGoodsInventory;
import com.xdf.ecommerce.goods.GoodsInfo;
import com.xdf.ecommerce.goods.SimpleGoodsInfo;
import com.xdf.ecommerce.service.IGoodsService;
import com.xdf.ecommerce.vo.PageSimpleGoodsInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author chanchaw
 * @create 2025-10-28 8:50
 */
@RequiredArgsConstructor
@Service
@Transactional(rollbackFor = Exception.class)
public class GoodsServiceImpl implements IGoodsService {
    private final StringRedisTemplate redisTemplate;
    private final EcommerceGoodsMapper dao;

    @Override
    public List<SimpleGoodsInfo> queryGoods4DBAndCached2Redis(List<Long> ids){
        if(null == ids || ids.size() == 0) return null;
        List<SimpleGoodsInfo> ret = new ArrayList<>();
        for (Long id : ids) {
            EcommerceGoods g = dao.selectOneById(id);
            ret.add(EcommerceGoods.toSimple(g));
        }

        Map<String,String> map = new HashMap<>(ret.size());
        ret.forEach(g -> map.put(g.getId().toString(), JSON.toJSONString(g)));
        redisTemplate.opsForHash().putAll(GoodsConstant.ECOMMERCE_GOODS_DICT_KEY, map);// 向redis写入数据
        return ret;
    }
    /**
     * 将从 redis 读取到的缓存数据转换为 SimpleGoodsInfo 集合
     * @param cachedSimpleGoodsInfo
     * @return
     */
    @Override
    public List<SimpleGoodsInfo> parseCacheGoodsInfo(List<Object> cachedSimpleGoodsInfo){
        return cachedSimpleGoodsInfo.stream().map(g -> JSON.parseObject(g.toString(), SimpleGoodsInfo.class)).collect(Collectors.toList());
    }
    @Override
    public EcommerceGoods findByGoodsNameAndMultCategory(String goodsCategory, String brandCategory, String goodsName){
        return dao.findByGoodsNameAndMultCategory(goodsCategory, brandCategory, goodsName);
    }
    @Override
    public List<EcommerceGoods> insertBatch(List<EcommerceGoods> goods){
        if(null == goods || goods.size() <= 0) return null;
        List<EcommerceGoods> ret = new ArrayList<>();
        for (EcommerceGoods good : goods) {
            int i = dao.insertSelective(good);
            ret.add(dao.selectOneById(good.getId()));
        }
        return ret;
    }
    @Override
    public List<GoodsInfo> getGoodsInfo8Id(List<Long> ids) {
        List<EcommerceGoods> goodsList = dao.selectListByIds(ids);
        List<GoodsInfo> ret = goodsList.stream().map(item -> EcommerceGoods.toGoodsInfo(item)).collect(Collectors.toList());
        return ret;
    }

    @Override
    public PageSimpleGoodsInfo getSimpleGoodsInfo8Page(int page) {
//        Pageable pageable = PageRequest.of(page - 1, 10, Sort.by("id").descending());
        return null;
    }

    @Override
    public SimpleGoodsInfo getSimpleGoodsInfo8Id(Long id) {
        EcommerceGoods goods = dao.selectOneById(id);
        return EcommerceGoods.toSimple(goods);
    }

    /**
     * 批量扣减库存
     * @param deductGoodsInventoryList
     * @return
     */
    @Override
    public Boolean deductGoodsInventory(List<DeductGoodsInventory> deductGoodsInventoryList) {
        for (DeductGoodsInventory item : deductGoodsInventoryList) {
            Long goodsId = item.getGoodsId();
            EcommerceGoods goods = dao.selectOneById(goodsId);
            Long inventory = goods.getInventory();
            Long remain = inventory - item.getCount();
            if(remain < 0) throw new RuntimeException(goods.getGoodsName() + " 库存不足!");
            goods.setInventory(remain);
            dao.update(goods);
        }
        return true;
    }
}
